﻿using System;
using UnityEditor;
using UnityEngine;

namespace Nirvana
{
	public enum ModelOptimizeMeshType
    {
		None=0,
		Everything,
		PolygonOrder,
		VertexOrder
    }

	[Serializable]
	public class ModelImportConfig
    {
		[SerializeField]
		private FloatVariate scaleFactor;

		[SerializeField]
		private BoolVariate isReadable;

		[SerializeField]
		private ModelOptimizeMeshTypeVariate optimizeMesh;

		[SerializeField]
		private ModelImporterMeshCompressionVariate meshCompression;

		[SerializeField]
		private BoolVariate weldVertices;

		[SerializeField]
		private BoolVariate importBlendShapes;

		[SerializeField]
		private BoolVariate importVisibility;

		[SerializeField]
		private BoolVariate importCameras;

		[SerializeField]
		private BoolVariate importLights;

		[SerializeField]
		private BoolVariate preserveHierarchy;

		[SerializeField]
		private BoolVariate generateColliders;

		[SerializeField]
		private BoolVariate keepQuads;

		
		[SerializeField]
		private BoolVariate swapUVChannels;


		[SerializeField]
		private ModelImporterNormalsVariate normals;


		[SerializeField]
		private FloatVariate normalSmoothingAngle;


		[SerializeField]
		private ModelImporterTangentsVariate tangents;


		[SerializeField]
		private BoolVariate uv2;
		[SerializeField]
		private BoolVariate uv3_4;
		[SerializeField]
		private BoolVariate color;
		[SerializeField]
		private BoolVariate tangentChannel;

		[SerializeField]
		private BoolVariate addNirvanaRenderer;
        [SerializeField]
        private BoolVariate clearDefaultMaterial;
        [SerializeField]
        private BoolVariate replaceDefaultMaterial;


		public void MatchRule(ModelImporter modelImporter)
        {
            if (scaleFactor.IsHasValue())
            {
				modelImporter.globalScale = scaleFactor.GetValue();
			}
			if (isReadable.IsHasValue())
			{
				modelImporter.isReadable = isReadable.GetValue();
			}
			if (optimizeMesh.IsHasValue())
			{
#if UNITY_2019_1_OR_NEWER
                switch (optimizeMesh.GetValue())
                {
					case ModelOptimizeMeshType.None:
						modelImporter.optimizeMeshPolygons = false;
						modelImporter.optimizeMeshVertices = false;
						break;
					case ModelOptimizeMeshType.Everything:
						modelImporter.optimizeMeshPolygons = true;
						modelImporter.optimizeMeshVertices = true;
						break;
					case ModelOptimizeMeshType.PolygonOrder:
						modelImporter.optimizeMeshPolygons = true;
						modelImporter.optimizeMeshVertices = false;
						break;
					case ModelOptimizeMeshType.VertexOrder:
						modelImporter.optimizeMeshPolygons = false;
						modelImporter.optimizeMeshVertices = true;
						break;

				}
#else
                modelImporter.optimizeMesh = optimizeMesh.GetValue() != ModelOptimizeMeshType.None;
#endif
            }
			if (meshCompression.IsHasValue())
			{
				modelImporter.meshCompression = meshCompression.GetValue();
			}
			if (weldVertices.IsHasValue())
			{
				modelImporter.weldVertices = weldVertices.GetValue();
			}

			if (generateColliders.IsHasValue())
			{
				modelImporter.addCollider = generateColliders.GetValue();
			}
			if (normals.IsHasValue())
			{
				modelImporter.importNormals = normals.GetValue();
			}
			if (normalSmoothingAngle.IsHasValue())
			{
				modelImporter.normalSmoothingAngle = normalSmoothingAngle.GetValue();
			}
			if (tangents.IsHasValue())
			{
				modelImporter.importTangents = tangents.GetValue();
			}

			if (importBlendShapes.IsHasValue())
			{
				modelImporter.importBlendShapes = importBlendShapes.GetValue();
			}
  
            if (importVisibility.IsHasValue())
			{
				modelImporter.importVisibility = importVisibility.GetValue();
			}
			if (importCameras.IsHasValue())
			{
				modelImporter.importCameras = importCameras.GetValue();
			}
			if (importLights.IsHasValue())
			{
				modelImporter.importLights = importLights.GetValue();
			}
			if (preserveHierarchy.IsHasValue())
			{
				modelImporter.preserveHierarchy = preserveHierarchy.GetValue();
			}
			if (keepQuads.IsHasValue())
			{
				modelImporter.keepQuads = keepQuads.GetValue();
			}
			if (swapUVChannels.IsHasValue())
			{
				modelImporter.swapUVChannels = swapUVChannels.GetValue();
			}
            
#if UNITY_2019_1_OR_NEWER 
			modelImporter.SaveAndReimport(); //unity2019版本需要主动刷新
#endif
		}

		public void MatchRule(GameObject model)
		{
			var rFilters = model.GetComponentsInChildren<MeshFilter>(true);
			for (int filter_index = 0; filter_index < rFilters.Length; filter_index++)
			{
				if (tangentChannel.IsHasValue() && tangentChannel.GetValue())
				{
					rFilters[filter_index].sharedMesh.tangents = null;
				}
				if (uv2.IsHasValue() && uv2.GetValue())
				{
					rFilters[filter_index].sharedMesh.uv2 = null;
				}
				if (uv3_4.IsHasValue() && uv3_4.GetValue())
                {
					rFilters[filter_index].sharedMesh.uv3 = null;
					rFilters[filter_index].sharedMesh.uv4 = null;
				}
				if (color.IsHasValue() && color.GetValue())
				{
					rFilters[filter_index].sharedMesh.colors = null;
					rFilters[filter_index].sharedMesh.colors32 = null;
				}

			}
			var mFilters = model.GetComponentsInChildren<SkinnedMeshRenderer>();
			for (int filter_index = 0; filter_index < mFilters.Length; filter_index++)
			{
				if (tangentChannel.IsHasValue() && tangentChannel.GetValue())
				{
					mFilters[filter_index].sharedMesh.tangents = null;
				}
				if (uv2.IsHasValue() && uv2.GetValue())
				{
					mFilters[filter_index].sharedMesh.uv2 = null;
				}
				if (uv3_4.IsHasValue() && uv3_4.GetValue())
				{
					mFilters[filter_index].sharedMesh.uv3 = null;
					mFilters[filter_index].sharedMesh.uv4 = null;
				}
				if (color.IsHasValue() && color.GetValue())
				{
					mFilters[filter_index].sharedMesh.colors = null;
					mFilters[filter_index].sharedMesh.colors32 = null;
				}
			}

 #if !UNITY_2019_1_OR_NEWER //2019以以下版本就处理
            if (clearDefaultMaterial.IsHasValue() && clearDefaultMaterial.GetValue())
            {
                var skin = model.GetComponentsInChildren<SkinnedMeshRenderer>(true);
                for (int i = 0; i < skin.Length; i++)
                {
                    var material = skin[i].sharedMaterial;
                    if (material.name.Contains("Default-Material") || material.name.Contains("Default_Mat") || material.name == ""
                        || material.name.Contains("– Default") || material.name.Contains("No Name"))
                        skin[i].sharedMaterials = new Material[skin[i].sharedMaterials.Length];
                    //skin[i].sharedMaterial = LoadDefaultMaterial();
                }

                var mRenderer = model.GetComponentsInChildren<MeshRenderer>(true);
                for (int i = 0; i < mRenderer.Length; i++)
                {
                    var material = mRenderer[i].sharedMaterial;
                    if (material.name.Contains("Default-Material") || material.name.Contains("Default_Mat") || material.name == "" 
                        || material.name.Contains("– Default") || material.name.Contains("No Name"))
                         mRenderer[i].sharedMaterials = new Material[mRenderer[i].sharedMaterials.Length];
                        //mRenderer[i].sharedMaterial = LoadDefaultMaterial();
                }
            }
			 if (replaceDefaultMaterial.IsHasValue() && replaceDefaultMaterial.GetValue())
            {
                var skin = model.GetComponentsInChildren<SkinnedMeshRenderer>(true);
                for (int i = 0; i < skin.Length; i++)
                {
                    var material = skin[i].sharedMaterial;
                    if (material == null) continue;
                    if (material.name.Contains("Default-Material") || material.name.Contains("Material #") || material.name == ""
                    || material.name.Contains("– Default") || material.name.Contains("No Name"))
                        skin[i].sharedMaterial = LoadDefaultMaterial();
                }

                var mRenderer = model.GetComponentsInChildren<MeshRenderer>(true);
                for (int i = 0; i < mRenderer.Length; i++)
                {
                    var material = mRenderer[i].sharedMaterial;
                    if (material == null) continue;
                    if (material.name.Contains("Default-Material") || material.name.Contains("Material #") || material.name == ""
                    || material.name.Contains("– Default") || material.name.Contains("No Name"))
                    {
                        mRenderer[i].sharedMaterial = LoadDefaultMaterial();
                    }

                }

              
            }
#endif
			if (addNirvanaRenderer.IsHasValue())
			{
				var renders = model.GetComponentsInChildren<Renderer>(true);
				if (renders != null)
					foreach (var r in renders)
					{
                        if (addNirvanaRenderer.GetValue())
                        {
							NirvanaRenderer orAddComponent = r.gameObject.GetOrAddComponent<NirvanaRenderer>();
							if (r.sharedMaterials != null && r.sharedMaterials.Length > 0)
							{
								orAddComponent.Materials = r.sharedMaterials;
							}
                        }
                        else
                        {
							NirvanaRenderer orAddComponent = r.gameObject.GetComponent<NirvanaRenderer>();
							if(orAddComponent!=null)GameObject.DestroyImmediate(orAddComponent);

						}

					}
			}
		}

        Material LoadDefaultMaterial()
        {
            var materialPath = "Assets/Resources/BuildInShader/Default_Mat.mat";
            Material defaultMaterial = AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)) as Material;
            if (defaultMaterial == null)
            {
                defaultMaterial = new Material(Shader.Find("Standard"));
                AssetDatabase.CreateAsset(defaultMaterial, materialPath);
                AssetDatabase.Refresh();
            }
            return defaultMaterial;

        }
    }
}

